import random;

class BlackBoard(object):
    def __init__(self, inputSim):
        self.stgm = inputSim.stgm;
        self.graph = self.stgm.Graph();
        self.inputSim = inputSim;
        self.aStates = inputSim.aStates;
    
    def getIndex(self, aAct):
        for i in range(len(self.aStates)): #For each State
            bMatch = True;
            if aAct[0] == self.aStates[i][0]: #If has same Activity name
                if len(aAct[1])!=len(self.aStates[i][1]): #If has Diff # Args
                    bMatch = False;
                for j in range(len(aAct[1])): #For each Arg element
                    if ((aAct[1][j]=="*" and self.aStates[i][1][j]!="*") or
                        (aAct[1][j]!="*" and self.aStates[i][1][j]=="*")):
                        bMatch = False;
                if bMatch==True:
                    return i;
        return -1;
    
    def getMatches(self, aActT0, actT1):
        aMatches = [];
        for i in range(len(aActT0)): #For each Act in t-1
            for j in range(len(aActT0[i].aPersons)): #For each Arg t-1 element
                if aActT0[i].aPersons[j]=="*":
                    continue;
                bMatch = False;
                for k in range(len(actT1[1])): #For each Arg t element
                    if(aActT0[i].aPersons[j] == actT1[1][k]):
                        bMatch = True;
                        break;
                if bMatch==False:
                    break;
            if bMatch==True:
                aMatches.append([i+1, [aActT0[i].sActivity, aActT0[i].aPersons]]);
        return aMatches;
    
    def getMatch(self, actT0, actT1):
        for j in range(len(actT0[1])): #For each Arg t-1 element
            if actT0[1][j]=="*":
                continue;
            bMatch = False;
            for k in range(len(actT1[1])): #For each Arg t element
                if(actT0[1][j] == actT1[1][k]):
                    bMatch = True;
                    break;
            if bMatch==False:
                break;
        return bMatch;
    
    def printLinkActs(self, nTime):
        for i in range(len(self.inputSim.aActs_Time[nTime])): #For each Act[t]
            aActT1 = self.inputSim.aActs_Time[nTime][i];
            sAct1 = aActT1.getKeyTexts();
            nIndexT1 = self.getIndex(sAct1);
            print sAct1, "->", "Transition:", nIndexT1, "->", self.aStates[nIndexT1];
            for j in range(len(self.inputSim.aActs_Time[0])): #For each Act[t-1]
                actT0 = self.inputSim.aActs_Time[0][j];
                sAct0 = actT0.getKeyTexts();
                nIndexA0 = self.getIndex(sAct0);
                nIndexA1 = self.getIndex(sAct1);
                if self.getMatch(sAct0, sAct1):
                    print "Match:", [j+1, sAct0], "->", "Transition:", nIndexA0, "->", self.aStates[nIndexA0], "->", self.inputSim.aTrans[nIndexA0][nIndexA1];
                else:
                    print "No-Match:", [j+1, sAct0], "->", "Prior:", nIndexA0, "->", self.aStates[nIndexA0], "->", self.inputSim.aPriors[nIndexA1];
            print "";
            
    def linkActivities(self, nTime):
        for i in range(len(self.inputSim.aActs_Time[nTime])): #For each Act[t]
            aActT1 = self.inputSim.aActs_Time[nTime][i];
            sAct1 = aActT1.getKeyTexts();
            nPrior = self.inputSim.aPriors[self.getIndex(sAct1)];
            aActT1.addToGraph(self.graph, nPrior);
            [aActs, aProbs] = self.getPastLinks(nTime-1, sAct1);
#            sActs = [];
#            for j in range(len(aActs)):
#                sActs.append(aActs[j].name);
#            print [aActT1.rootAct.name, sActs, aProbs];
            self.graph.addnode(aActT1.rootAct, aActs, aProbs);
#        self.graph.setup();

    def getPastLinks(self, nT0, sAct1):
        aActs, aProbs = [], [];
        nIndexA1 = self.getIndex(sAct1);
#        print "";
        if nT0 < 0:
            #Send Prior
            aProbs.append(self.inputSim.aPriors[nIndexA1]);
#            print "No-Match: ->", "Prior:", nIndexA1, "->", self.aStates[nIndexA1], "->", self.inputSim.aPriors[nIndexA1];
            return [aActs, aProbs];
        for j in range(len(self.inputSim.aActs_Time[nT0])): #For each Act[t-1]
            actT0 = self.inputSim.aActs_Time[nT0][j];
            sAct0 = actT0.getKeyTexts();
            nIndexA0 = self.getIndex(sAct0);
            if self.getMatch(sAct0, sAct1):
                #Send Transition
                aProbs.append(self.inputSim.aTrans[nIndexA0][nIndexA1]);
                aActs.append(actT0.rootAct);
#                print "Match:", [j+1, sAct0], "->", "Transition:", nIndexA0, "->", self.aStates[nIndexA0], "->", self.inputSim.aTrans[nIndexA0][nIndexA1];
        if aActs==[]:
            #Send Prior
            aProbs.append(self.inputSim.aPriors[nIndexA1]);
#            print "NONE-Matches:", [j+1, sAct1], "->", "Prior:", nIndexA1, "->", self.aStates[nIndexA1], "->", self.inputSim.aPriors[nIndexA1];
        return [aActs, aProbs];
                
                
                
                    